package com.mall.user.services;

import com.mall.user.IRegisterService;
import com.mall.user.constants.SysRetCodeConstants;
import com.mall.user.dal.entitys.Member;
import com.mall.user.dal.entitys.UserVerify;
import com.mall.user.dal.persistence.MemberMapper;
import com.mall.user.dal.persistence.UserVerifyMapper;
import com.mall.user.dto.*;
import com.mall.user.registerVerification.RegisterMailDemo;
import com.mall.user.utils.ExceptionProcessorUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.Service;
import org.mindrot.jbcrypt.BCrypt;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import tk.mybatis.mapper.entity.Example;

import java.util.*;


/**
 * @author qugr
 * @create 2020-07-10 18:08
 */
@Slf4j
@Component
@Service
public class RegisterServiceImpl implements IRegisterService {

    @Autowired
    MemberMapper memberMapper;

    @Autowired
    UserVerifyMapper userVerifyMapper;

    @Autowired
    RedissonClient redissonClient;

    @Autowired
    RegisterMailDemo registerMailDemo;

    private final String KAPTCHA_UUID="kaptcha_uuid";

    @Override
    public UserRegisterResponse userRegister(UserRegisterRequest request, KaptchaCodeRequest kaptchaCodeRequest, Map<String,String> requestMap) {
        UserRegisterResponse response = new UserRegisterResponse();

        //校验验证码是否正确
        try{
            kaptchaCodeRequest.requestCheck();
            String redisKey = KAPTCHA_UUID + kaptchaCodeRequest.getUuid();
            RBucket<String> rBucket = redissonClient.getBucket(redisKey);
            String code = rBucket.get();
            log.info("请求的redisKey={},请求的code={},从redis获得的code={}",redisKey,kaptchaCodeRequest.getCode(),code);
            if(StringUtils.isBlank(code) || !kaptchaCodeRequest.getCode().equalsIgnoreCase(code)){
                response.setCode(SysRetCodeConstants.KAPTCHA_CODE_ERROR.getCode());
                response.setMsg(SysRetCodeConstants.KAPTCHA_CODE_ERROR.getMessage());
                return response;
            }
        } catch (Exception e) {
            log.error("KaptchaServiceImpl.validateKaptchaCode occur Exception :"+e);
            ExceptionProcessorUtils.wrapperHandlerException(response,e);
            return response;
        }

        //校验邮箱是否已经注册
        Example example = new Example(Member.class);
        if (StringUtils.isNotBlank(request.getEmail())) {
            example.createCriteria().andEqualTo("state", 1).andEqualTo("email",request.getEmail());
            if (!memberMapper.selectByExample(example).isEmpty()) {
                response.setCode(SysRetCodeConstants.SYSTEM_ERROR.getCode());
                response.setMsg(SysRetCodeConstants.SYSTEM_ERROR.getMessage() + "   邮箱已经被注册");
                return response;
            }
        }

        //校验用户名是否存在
        example.clear();
        if (StringUtils.isNotBlank(request.getUserName())) {
            example.createCriteria().andEqualTo("state", 1).andEqualTo("username",request.getUserName());
            if (!memberMapper.selectByExample(example).isEmpty()) {
                response.setCode(SysRetCodeConstants.USERNAME_ALREADY_EXISTS.getCode());
                response.setMsg(SysRetCodeConstants.USERNAME_ALREADY_EXISTS.getMessage());
                return response;
            }
        }

        //向用户表中插⼊一条记录
        Member member = new Member();
        Date registerDate = new Date();
        member.setEmail(request.getEmail());
        member.setUsername(request.getUserName());
        member.setState(1);
        member.setCreated(registerDate);
        member.setUpdated(registerDate);
        member.setIsVerified("N");

        member.setPassword(BCrypt.hashpw(request.getUserPwd(), BCrypt.gensalt()));

        int insert2Member = memberMapper.insertSelective(member);
        if (insert2Member != 1) {
            response.setCode(SysRetCodeConstants.USER_REGISTER_FAILED.getCode());
            response.setMsg(SysRetCodeConstants.USER_REGISTER_FAILED.getMessage());
            return response;
        }

        //向用户验证表中插⼊一条记录
        UserVerify userVerify = new UserVerify();
        userVerify.setUsername(request.getUserName());
        userVerify.setRegisterDate(registerDate);
        //注册时生成的唯一号
        String uuid= request.getUserName() + UUID.randomUUID().toString();
        userVerify.setUuid(uuid);
        userVerify.setIsVerify("N");
        userVerify.setIsExpire("N");

        int insert2UserVerify = userVerifyMapper.insertSelective(userVerify);
        if (insert2UserVerify != 1) {
            response.setCode(SysRetCodeConstants.USER_REGISTER_VERIFY_FAILED.getCode());
            response.setMsg(SysRetCodeConstants.USER_REGISTER_VERIFY_FAILED.getMessage());
            return response;
        }

        response.setCode(SysRetCodeConstants.SUCCESS.getCode());
        response.setMsg(SysRetCodeConstants.SUCCESS.getMessage());

        //发送激活账户邮件
        Map<String,String> mailMap = new HashMap<>();
        mailMap.put("target",request.getEmail());
        String localAddr = requestMap.get("localAddr");
        if ("0:0:0:0:0:0:0:1".equals(localAddr)) {
            localAddr = "localhost";
        }
        mailMap.put("url","http://" + localAddr + ":" + requestMap.get("localPort") + "/user/verify?uuid=" + uuid + "&username=" + request.getUserName());
        new Thread(() -> registerMailDemo.sendMail(mailMap)).start();
        return response;
    }

    @Override
    public UserVerifyResponse userVerify(UserVerifyRequest request) {
        UserVerifyResponse response = new UserVerifyResponse();
        //校验入参是否为空
        if(StringUtils.isBlank(request.getUserName())||StringUtils.isBlank(request.getUuid())){
            response.setCode(SysRetCodeConstants.REQUISITE_PARAMETER_NOT_EXIST.getCode());
            response.setMsg(SysRetCodeConstants.REQUISITE_PARAMETER_NOT_EXIST.getMessage());
            return response;
        }

        //是否存在该未激活的注册用户
        Example example = new Example(Member.class);
        example.createCriteria().andEqualTo("state",1).andEqualTo("username",request.getUserName());
        List<Member> members = memberMapper.selectByExample(example);
        if(members.isEmpty()) {
            response.setCode(SysRetCodeConstants.USER_INFOR_INVALID.getCode());
            response.setMsg(SysRetCodeConstants.USER_INFOR_INVALID.getMessage());
            return response;
        }

        //是否存在注册激活信息
        example.clear();
        example = new Example(UserVerify.class);
        example.createCriteria().andEqualTo("uuid",request.getUuid()).andEqualTo("username",request.getUserName());
        List<UserVerify> userVerifys = userVerifyMapper.selectByExample(example);
        if(userVerifys.isEmpty()) {
            response.setCode(SysRetCodeConstants.USERVERIFY_INFOR_INVALID.getCode());
            response.setMsg(SysRetCodeConstants.USERVERIFY_INFOR_INVALID.getMessage());
            return response;
        }
        //激活该用户
        UserVerify userVerify = userVerifys.get(0);
        userVerify.setIsVerify("Y");
        userVerifyMapper.updateByExample(userVerify,example);

        //将该用户更新为已激活
        example.clear();
        example = new Example(Member.class);
        example.createCriteria().andEqualTo("username",request.getUserName());
        Member member = members.get(0);
        member.setIsVerified("Y");
        memberMapper.updateByExample(member,example);

        response.setCode(SysRetCodeConstants.SUCCESS.getCode());
        response.setMsg(SysRetCodeConstants.SUCCESS.getMessage());

        return response;
    }
}
